package cn.craftyun.serverlist.service.impl;

import cn.craftyun.serverlist.entity.Server;
import cn.craftyun.serverlist.entity.User;
import cn.craftyun.serverlist.exception.ServiceFailedException;
import cn.craftyun.serverlist.mapper.ServerMapper;
import cn.craftyun.serverlist.mapper.UserMapper;
import cn.craftyun.serverlist.param.UserLoginParam;
import cn.craftyun.serverlist.param.UserUpdatePassParam;
import cn.craftyun.serverlist.service.IUserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.nio.charset.StandardCharsets;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author FanHuaCloud
 * @since 2021-09-22
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Resource
    private HttpSession httpSession;
    @Resource
    private ServerMapper serverMapper;

    /**
     * 获取登录用户信息
     *
     * @return 登录用户
     */
    @Override
    public User getLoginUser() {
        return (User) httpSession.getAttribute("loginUser");
    }

    /**
     * 用户登录
     *
     * @param param 用户登录参数
     * @return 用户信息
     */
    @Override
    public User userLogin(UserLoginParam param) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<User>()
                .eq("username", param.getUsername())
                .last("limit 1");
        User user = getBaseMapper().selectOne(queryWrapper);

        if (user == null) {
            throw new ServiceFailedException("用户不存在");
        }
        // 密码加密
        String md5Password = DigestUtils.md5DigestAsHex(param.getPassword().getBytes(StandardCharsets.UTF_8));
        if (!user.getPassword().equals(md5Password)) {
            throw new ServiceFailedException("用户密码错误");
        }
        return user;
    }

    /**
     * 用户注册
     *
     * @param user 用户
     */
    @Transactional
    @Override
    public void userReg(User user) {
        // 查询已有用户
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("email", user.getEmail()).or().eq("player_name", user.getPlayerName()).last("limit 1");
        User queryUser = getBaseMapper().selectOne(queryWrapper);
        if (queryUser != null) {
            throw new ServiceFailedException("注册失败,邮箱或用户名已存在");
        }
        // 注册
        getBaseMapper().insert(user);
    }

    /**
     * 删除用户
     *
     * @param id 用户ID
     */
    @Transactional
    @Override
    public void delete(Integer id) {
        User user = getBaseMapper().selectById(id);
        if (user == null) {
            throw new ServiceFailedException("用户不存在");
        }
        // 查询服务器
        QueryWrapper<Server> serverQueryWrapper = new QueryWrapper<Server>().eq("user_id", id);
        if (serverMapper.selectCount(serverQueryWrapper) > 0) {
            throw new ServiceFailedException("请先删除对应用户的服务器");
        }
        getBaseMapper().deleteById(id);
    }

    /**
     * 更新用户密码
     *
     * @param userId 用户ID
     * @param param  更新参数
     */
    @Override
    public void updatePass(Integer userId, UserUpdatePassParam param) {
        String queryUserPass = getBaseMapper().selectById(userId).getPassword();
        if (!DigestUtils.md5DigestAsHex(param.getOldPassword().getBytes(StandardCharsets.UTF_8)).equals(queryUserPass)) {
            throw new ServiceFailedException("原密码错误");
        }

        User updateUser = new User();
        updateUser.setId(userId);
        updateUser.setPassword(DigestUtils.md5DigestAsHex(param.getPassword().getBytes(StandardCharsets.UTF_8)));
        getBaseMapper().updateById(updateUser);
    }

    /**
     * 分页获取用户列表
     *
     * @param page        分页对象
     * @param filterParam 筛选参数
     * @return 用户分页对象
     */
    @Override
    public IPage<User> pageUser(IPage<User> page, User filterParam) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (StringUtils.hasText(filterParam.getUsername())) {
            queryWrapper.like("username", filterParam.getUsername());
        }
        if (StringUtils.hasText(filterParam.getEmail())) {
            queryWrapper.like("email", filterParam.getEmail());
        }
        if (filterParam.getUserRole() != null) {
            queryWrapper.eq("user_role", filterParam.getUserRole());
        }
        queryWrapper.orderByAsc("id");

        return getBaseMapper().selectPage(page, queryWrapper);
    }
}
